Lorenzo Drufuca
12/10/2023
We generally write a computer program using a high-level language. A high-level language is one that is understandable by us, humans. This is called source code.
However, a computer does not understand high-level language. It only understands the program written in 0’s and 1’s in binary, called the machine code.
To convert source code into machine code, we use either a compiler or an interpreter.
Both compilers and interpreters are used to convert a program written in a high-level language into machine code understood by computers. However, there are differences between how an interpreter and a compiler works.
| Interpreter | Compiler |
|---|---|
| Translates program one statement at a time | Scans the entire program and translates it as a whole into machine code |
| No intermediate object code is generated, hence is memory efficient | Generates intermediate object code which further requires linking, hence requires more memory |
| Programming languages like JavaScript, Python, Ruby use interpreters | Programming languages like C, C++, Java use compilers |
Once Python is installed, typing python in the command line will invoke the interpreter in immediate mode. You can directly type in Python code, and press Enter to get the output.
Then you could use
It is possible to use any text editing software to write a Python script file. You just need to save it with the .py extension.
IDE (Integrated Development Environment) is a piece of software (basically a text editor) that provides useful features like code hinting, syntax highlighting and checking, file explorers, etc. to the programmer for application development.
JupyterLab is a web-based interactive development environment for Jupyter Notebooks, code, and data.
The Jupyter Notebook is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and narrative text.
We will use Juyter Notebook as our workspace for Python coding.
An identifier is a name given to entities like class, functions, variables, etc. It helps to differentiate one entity from another.
Keywords are the reserved words in Python. It is not possible to use a keywords as an identifier.
There are 33 keywords in Python 3.7. This number can vary slightly over the course of time.
Instructions that a Python interpreter can execute are called statements. The end of a statement is marked by a newline character even if is possible to make multi-line statements.
They describe what is going on inside a program, so that a person looking at the source code does not have a hard time figuring it out. You might forget the key details of the program you just wrote in a month’s time. So taking the time to explain these concepts in the form of comments is always useful.
A code block (body of a function, loop, etc.) starts with indentation and ends with the first unindented line. The amount of indentation is up to you, but it must be consistent throughout that block.
A variable is a named location used to store data in the memory. It is helpful to think of variables as a container that holds data that can be changed later in the program.
What happen if you write more than one variable in a chunk and run it?
Python will always visualize the output of the last statement of the chunk, in this example the last variable.
To check the value of multiple variables together you could use the function
Changing the value of a variable.
and visualize the variable again
or
Remember a variable will not change without assigning it to a new value.
Try to not run the code, which is the value of a, b and c?
Every value in Python has a datatype. Since everything is an object in Python programming, data types are actually classes and variables are instance (object) of these classes (We will see this later).
Integers, floating point numbers and complex numbers fall under Python numbers category. They are defined as int, float and complex classes in Python.
It is possible to use function
to know which class a variable or a value belongs to.
Integers can be of any length, it is only limited by the memory available.
A floating-point number is accurate up to 15 decimal places. Integer and floating points are separated by decimal points. 1 is an integer, 1.0 is a floating-point number.
Complex numbers are written in the form, x + yj, where x is the real part and y is the imaginary part.
List is an ordered sequence of items. It is one of the most used datatype in Python and is very flexible. All the items in a list do not need to be of the same type.
Declaring a list is pretty straight forward. Items separated by commas are enclosed within brackets [ ].
Which type are the elements of the list above?
It is possible to use the slicing operator [ ] to extract an item or a range of items from a list. The index starts from 0 in Python.
Comments?
Lists are mutable, meaning, the value of elements of a list can be altered.
Tuple is an ordered sequence of items same as a list. The only difference is that tuples are immutable. Tuples once created cannot be modified.
Tuples are used to write-protect data and are usually faster than lists as they cannot change dynamically.
It is defined within parentheses () where items are separated by commas.
It is possible to use the slicing operator [] to extract items but we cannot change its value.
String is sequence of Unicode characters. You can use single quotes or double quotes to represent strings. Multi-line strings can be denoted using triple quotes, ’’’ or """.
Just like a list and tuple, the slicing operator [ ] can be used with strings. Strings, however, are immutable.
What happen if running this?
Set is an unordered collection of unique items. Set is defined by values separated by comma inside braces { }. Items in a set are not ordered.
Since, set are unordered collection, indexing has no meaning. Hence, the slicing operator [] does not work.
Comments?
Dictionary is an unordered collection of key-value pairs.
It is generally used when we have a huge amount of data. Dictionaries are optimized for retrieving data. We must know the key to retrieve the value.
In Python, dictionaries are defined within braces {} with each item being a pair in the form key:value. Key and value can be of any type.
Comments?
it is possible to convert between different data types by using different type conversion functions like:
What about this?
It si possible to convert one sequence to another.
A list of lists is a group of lists put togehter as indipendent elements of another list.
Comments?
It is possible to use the function
to output data to the standard output device as seen before.
In the second example, is possible to notice that a space was added between the string and the value of variable a. This is by default, but it is possible to change it following the syntax of the print() function:
The sep separator is used between the values. It defaults into a space character.
After all values are printed, end is printed. It defaults into a new line.
The file is the object where the values are printed and its default value is sys.stdout (screen). Here is an example to illustrate this.
Sometimes we would like to format our output to make it look attractive. This can be done by using the method
Here, the curly braces {} are used as placeholders.
Until now we talked about functions and methods. We will talk about them later, but for now just keep in mind that they are more or less the same excluding the fact that functions could be called indipendently instead methods must be linked to a specific object using the object.method() syntax
Comments?
It is possible to take the input from the user. In Python there is the function
with syntax
Where prompt is the string you wish to display to the user on the screen.
Comments?
It is possible to see that the entered value 10 is a string, not a number. To convert this into a number you can use int() or float() functions.
A module is a Python file (.py) containing Python statements.
Definitions,classes and functions inside a module can be imported inside the interactive interpreter in Python (or into another module) using the import keyword.
Python has pre-installed module called math which contains a variable pi assigned to the pi greco value.
It is possible to import this module
Now all the definitions inside math module are available in our enviroment.
While importing a module, Python looks at several places defined in sys.path. It is a list of directory locations where the module are stored. It is possible to add your own location to this list.
or
Operators are special symbols in Python that carry out arithmetic or logical computation. The value that the operator operates on is called the operand.
We will see here some of the most used operators with Python.
Arithmetic operators are used to perform mathematical operations like addition, subtraction, multiplication, etc.
| Operator | Meaning | Example |
|---|---|---|
| + | Add two operands | x + y+ 2 |
| - | Subtract right operand from the left | x - y- 2 |
| * | Multiply two operands | x * y |
| / | Divide left operand by the right one | x / y |
| ** | Exponent - left operand raised to the power of right | x**y |
Comparison operators are used to compare values. It returns either True or False according to the condition.
| Operator | Meaning | Example |
|---|---|---|
| > | Greater than | x > y |
| < | Less than | x < y |
| == | Equal to | x == y |
| != | Not equal to | x != y |
| >= | Greater than or equal to | x >= y |
| <= | Less than or equal to | x <= y |
Logical operators are the and, or, not operators.
| Operator | Meaning | Example |
|---|---|---|
| and | True if both the operands are true | x and y |
| or | True if either of the operands is true | x or y |
| not | True if operand is false | not x |
Bitwise operators act on operands as if they were strings of binary digits. They operate bit by bit, hence the name.
Assignment operators are used in Python to assign values to variables.
| Operator | Meaning | Equivalent to |
|---|---|---|
| = | x = 5 | x = 5 |
| += | x += 5 | x = x + 5 |
| -= | x -= 5 | x = x - 5 |
| *= | x *= 5 | x = x * 5 |
Python language offers some special types of operators like the identity operator or the membership operator.
| Operator | Meaning | Example |
|---|---|---|
| is | True if the operands are identical (refer to the same object) | x is True |
| is not | True if the operands are not identical (do not refer to the same object) | x is not True |
| Operator | Meaning | Example |
|---|---|---|
| in | True if value/variable is found in the sequence | 5 in x |
| not in | True if value/variable is not found in the sequence | 5 not in x |
Decision making is required when we want to execute a code only if a certain condition is satisfied.
The if elif else statement is used in Python for decision making.
Here, the program evaluates the test expression and will execute statement(s) only if the test expression is True.
If the test expression is False, the statement(s) is not executed.
In Python, the body of the if statement is indicated by the indentation. The body starts with an indentation and the first unindented line marks the end.
Python interprets non-zero values as True. None and 0 are interpreted as False.
Example
The if.. else statement evaluates test expression and will execute the body of if only when the test condition is True.
If the condition is False, the body of else is executed. Indentation is used to separate the blocks.
The elif is short for else if. It allows you to check for multiple expressions.
If the condition for if is False, it checks the condition of the next elif* block and so on.
If all the conditions are False, the body of else is executed.
Only one block among the several if.. elif.. else blocks is executed according to the condition.
The if block can have only one else block. But it can have multiple elif blocks.
We can have a if.. elif.. else statement inside another if.. elif.. else statement. This is called nesting in computer programming.
Any number of these statements can be nested inside one another. Indentation is the only way to figure out the level of nesting. They can get confusing, so they must be avoided unless necessary.
'''In this program, we input a number
check if the number is positive or
negative or zero and display
an appropriate message
This time we use nested if statement'''
num = float(input("Enter a number: "))
if num >= 0:
if num == 0:
print("Zero")
else:
print("Positive number")
else:
print("Negative number")The for loop in Python is used to iterate over a sequence (list, tuple, string) or other iterable objects. Iterating over a sequence is called traversal.
Here, val is the variable that takes the value of the item inside the sequence on each iteration.
Loop continues until we reach the last item in the sequence. The body of for loop is separated from the rest of the code using indentation.
It is possible to generate a sequence of numbers using the function
This function will generate numbers from 0 to 9 (10 numbers).
It is also possible define the start, stop and step size with the syntax
range(start, stop, step_size)
The function will generate numbers from start to (stop - 1) using a defined step_size (default is 1).
The range object is “lazy” in a sense because it doesn’t generate every number that it “contains” when it is created. However, it is not an iterator since it supports in and len operations. This function does not store all the values in memory; it would be inefficient. So it remembers the start, stop, step size and generates the next number on the go.
A for loop can have an optional else block as well. The else part is executed if the items in the sequence used in for loop exhausts.
The break keyword can be used to stop a for loop. In such cases, the else part is ignored.
The while loop in Python is used to iterate over a block of code as long as the test expression (condition) is true.
It is generally used when you don’t know the number of times to iterate beforehand.
In the while loop, test expression is checked first. The body of the loop is entered only if the test_expression evaluates to True. After one iteration, the test expression is checked again. This process continues until the test_expression evaluates to False.
In Python, the body of the while loop is determined through indentation.
Python interprets any non-zero value as True. None and 0 are interpreted as False.
Same as with for loops, while loops can also have an optional else block.
The else part is executed if the condition in the while loop evaluates to False.
The while loop can be terminated with a break statement. In such cases, the else part is ignored.
In Python, break and continue statements can alter the flow of a normal loop as we have seen in the previous slide.
The break statement terminates the loop containing it. Control of the program flows to the statement immediately after the body of the loop.
If the break statement is inside a nested loop (loop inside another loop), the break statement will terminate the innermost loop.
The continue statement is used to skip the rest of the code inside a loop for the current iteration only. Loop does not terminate but continues on with the next iteration.
In Python, a function is a group of related statements that performs a specific task.
Functions help break our program into smaller and modular chunks. As our program grows larger and larger, functions make it more organized and manageable.
Furthermore, it avoids repetition and makes the code reusable.
Function syntax:
def function_name(parameters): # parameters are optional
"""docstring""" # optional
statement(s)
return value # optionalExample of a function
Try to run the following chunk
Comments?
Comments?
The first string after the function header is called the docstring and is short for documentation string. It is briefly used to explain what a function does.
Although optional, documentation is a good programming practice. Unless you can remember what you had for dinner last week, always document your code.
This string is available to us as the attribute of the function
__doc__
The return statement is used to exit a function and go back to the place from where it was called using the syntax
return [expression_list]
This statement can contain an expression that gets evaluated and the value is returned. If there is no expression in the statement or the return statement itself is not present inside a function, then the function will return the None object.
In the second example, None is the returned value since greet() function directly prints the name and no return statement is used.
Try to make a greet2() function identical to the greet() function but with a return statement that return the input name.
Try it
Comments?
Parameters and variables defined inside a function are not visible from outside the function.
The lifetime of a variable is the period throughout which the variable exits in the memory. The lifetime of variables inside a function is as long as the function executes.
They are destroyed once we return from the function. Hence, a function does not remember the value of a variable from its previous calls.
We will talk about this later in the chapter of global and local variables.
In Python, it is possible to define a function that takes variable number of arguments.
Since we have called this function with two arguments, it runs smoothly and we do not get any error.
Up until now, functions had a fixed number of arguments. In Python, there are other ways to define a function that can take variable number of arguments.
Function arguments can have default values in Python.
We can provide a default value to an argument by using the assignment operator (=).
Try
And
In this function, the parameter name does not have a default value and is required (mandatory) during a call.
On the other hand, the parameter msg has a default value of “Good morning!”. So, it is optional during a call. If a value is provided, it will overwrite the default value.
Any number of arguments in a function can have a default value. But once you have a default argument, all the arguments to its right must also have default values.
When we call a function with some values, these values get assigned to the arguments according to their position.
Python allows functions to be called using keyword arguments. When we call functions in this way, the order (position) of the arguments can be changed.
It is possible to mix positional arguments with keyword arguments during a function call. But you have tot keep in mind that keyword arguments must follow positional arguments.
Sometimes, we do not know in advance the number of arguments that will be passed into a function. Python allows us to handle this kind of situation through function calls with an arbitrary number of arguments.
In the function definition, it is used an asterisk (*) before the parameter name to denote this kind of argument.
In Python is possible for a function to call itself. These types of construct are termed as recursive functions.
Factorial of a number is the product of all the integers from 1 to that number. > 1*2*3*4*5*6 = 720
This function generate the factorial of a given number
In the above example, factorial() is a recursive function as it calls itself.
def factorial(x):
"""This is a recursive function
to find the factorial of an integer"""
if x == 1:
return 1
else:
return (x * factorial(x-1))factorial(3) # 1st call with 3
3 * factorial(2) # 2nd call with 2
3 * 2 * factorial(1) # 3rd call with 1
3 * 2 * 1 # return from 3rd call as number=1
3 * 2 # return from 2nd call
6 # return from 1st callThis recursion ends when the number reduces to 1. This is called the base condition.
Every recursive function must have a base condition that stops the recursion or else the function calls itself infinitely.
The Python interpreter limits the depths of recursion to help avoid infinite recursions, resulting in stack overflows.
By default, the maximum depth of recursion is 1000. If the limit is crossed, it results in RecursionError.
In Python, an anonymous function is a function that is defined without a name.
While normal functions are defined using the def keyword in Python, anonymous functions are defined using the lambda keyword with the following syntax
lambda arguments: expression
Lambda functions can have any number of arguments but only one expression. The expression is evaluated and returned.
This function has no name. It returns a function object which is assigned to the identifier double.
We use lambda functions when we require a nameless function for a short period of time.
In Python, we generally use it as an argument to a higher-order function (a function that takes in other functions as arguments).
In Python, a variable declared outside of a function is known as a global scope variable. This means that a global variable can be accessed inside or outside a function.
Comments?
What if you want to change the value of x inside a function?
The output shows an error because Python treats x as a local variable and x is not defined inside doubler() (the local scope).
How to change a global variable in a local scope?
It is possible to use the keyword
global
Comments?
In Python, global keyword allows you to modify the variable outside of the current scope. It is used to create a global variable and make changes to the variable in a local context.
A variable declared inside the function’s body is known as a local variable.
Comments?
The output shows an error because you are trying to access a local variable y in a global scope whereas the local variable only works inside printer() (the local scope).
Comments?
In the above code, it is used the same name x for both global variable and local variable. You get a different result when you print the same variable because the variable is declared in both scopes, the local scope inside printer() and global scope outside printer().
Nonlocal keyword creates nonlocal variables that are used in nested functions whose local scope is not defined. This means that the variable can be neither in the local nor the global scope.
Remember that if you change the value of a nonlocal variable, the changes appear in the local variable.
Python is a multi-paradigm programming language. It supports different programming approaches.
One of the popular approaches to solve a programming problem is by creating objects. This is known as Object-Oriented Programming (OOP).
An object has two characteristics:
A parrot could be an object, as it has the following properties:
A class is a blueprint for the object. It specifies which
and which
actually define a Parrot.
A class for Parrot could be:
A class is a blueprint for the object.
It is possible to use the keyword
class
to define an empty class.
From class, we construct instances. An instance is a specific object created from a particular class.
When class is defined, only the description for the object is defined. Therefore, no memory or storage is allocated.
In the above program, it is created a class with the name Parrot. Then, the Parrot attributes are defined.
These attributes are defined inside the init method of the class. It is the initializer method that is first run as soon as the object is created.
AND YES, you could guess now that also Classes are objects in Python because they have their own methods to use (remind that methods are functions associated to object)
Then, it is possible to create instances of the Parrot class.
Here, blu and woo are references (value) to our new objects.
The instances attribute (attribute of object) are specific of each object you create.
You can also define class attributes that are attributes identical to all objects generated from that class.
Methods are functions defined inside the body of a class. They are used to define the behaviors of an object.
class Parrot:
# instance attributes
def __init__(self, name, age):
self.name = name
self.age = age
# instance method
def sing(self, song):
return "{} sings {}".format(self.name, song)
def dance(self):
return "{} is now dancing".format(self.name)In the above program, are defined two methods i.e sing() and dance(). These are called instance methods because they are called on an instance object i.e blu.
Now you can generate new objects and call methods on them.
Inheritance is a way of creating a new class for using details of an existing class without modifying it. The newly formed class is a derived class (or child class). Similarly, the existing class is a base class (or parent class).
Penguins are birds so you would think to create a parent bird class with a penguin child class
In the program below, two classes are created: Bird, parent class and Penguin, child class.
# parent class
class Bird:
def __init__(self,name):
self.name = name
def fly(self):
print("{} flyes in the sky.".format(self.name))
def swim(self):
print("{} swims in the sea.".format(self.name))
# child class
class Penguin(Bird):
def __init__(self,name):
self.name = name
def fly(self):
print("{} cannot fly!".format(self.name))
def freezeResistence(self):
print("{} resists to freezing conditions".format(self.name))Then it is possible to generate a bird and a penguin
Now try the following by looking the 2 classes definition
Comments?
The child class inherits the method of parent class.
Now try the following by looking the 2 classes definition
Comments?
The child class modified the behavior of the parent class.
Now try the following by looking the 2 classes definition
Comments?
Child class extended the methods of the parent class without modifying the parent class.
Using OOP in Python, it is possible to restrict access to methods and variables. This prevents data from direct modification which is called encapsulation. In Python, we denote private attributes using underscore as the prefix.
Create the object
Comments?
Polymorphism is an ability (in OOP) to use a common interface for multiple forms.
In other words it is possible to create a function able to call a specific method of any object.
Create the objects
Using the common interface to call the fly() method on both objects